(define (square x) (* x x))

(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

(define (improve guess x)
  (average guess (/ x guess)))

(define (average x y)
  (/ (+ x y) 2))

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

(define (sqrt x)
  (sqrt-iter 1.0 x))



(sqrt 0.0000001)
;resulta em 0.03135649010771716, deveria ser 0.00031622776601683794

;No primeiro caso, o erro acontece porque o valor da raiz é menor que a precisão
;sendo usada (0.001). Por exemplo,

(good-enough? 0.03135649010771716 0.0000001)

;dá true quando deveria dar false, pois (0.0313 ** 2) - 0.0000001
; vale 0.00097959000000000002, o que ele considera um erro aceitável (< 0.001)

;(sqrt 1e64)
;trava!

;No segundo caso, o erro acontece porque a precisão dos números não
;é alta o suficiente para verificar se eles diferem por menos de 0.001, por eles
;serem muito grandes. Por exemplo,

(good-enough? 1e32 1e64)

;dá false quando deveria dar true, pois (1e32 ** 2) - 1e64 vale
;1.4615016373309029e+48, o que ele não considera um erro aceitável (< 0.001)



;considera um chute cuja relação novo chute / chute seja suficientemente próxima
;de 1. Talvez seja melhor comparar com o chute anterior ao invés de calcular
;o próximo, mas aí teria que tratar o chute anterior inicial, etc...
(define (fixed-good-enough? guess x)
  (<
   (abs (- 1.0 (/ (improve guess x) guess)))
   1e-5))

(define (fixed-sqrt-iter guess x)
  (if (fixed-good-enough? guess x)
      guess
      (fixed-sqrt-iter (improve guess x)
                 x)))

(define (fixed-sqrt x)
  (fixed-sqrt-iter 1.0 x))

(fixed-sqrt 0.0000001)
;     dá 0.00031622776664863746
;"certo" 0.00031622776601683794

(fixed-sqrt 1e64)
;   dá 1.0000046085713034e+032
;certo 1.0000000000000000e+032
